<?php
header('Content-Type: text/html; charset=UTF-8');
/**
 * 
 * 文件上传
 * @author xilou <chenyong@sun309.cn>
 * @version 2010-6-7 05:17:50 SVN:730
 * @package sun
 * @subpackage util
 * @copyright Copyright (c) 2009-2029 All rights reserved (Sun Medical Net)
 * <br>
 * <br>Modified-Log: any modify,please add log as follow!
 * <br>*****************************************************
 * <br>Modified-Date: 2010-6-7
 * <br>Modified-By: xilou
 * <br>Modified-Content:do not send validate smm when card-issued data import
 * <br>******************************************************
 * <br>*****************************************************
 * <br>Modified-Date: 2010-05-27
 * <br>Modified-By: xilou
 * <br>Modified-Content:do not send validate smm when card-issued data import
 * <br>******************************************************
 */
class Upload
{
	private $config = array();
	private $result = array();
	
	public function __construct($_config)
	{
		/*
		$_config = array(
			'file-max-size'      => '最大可以上传多少kb',
			'file-type'          => '允许上传的文件类型，格式：gif|jpeg|png',
			'file-new-type'      => '将上传的文件统一转为此类型，如统一转为gif格式，不设置则保存为上传的文件类型',
			'file-path'          => '上传路径，相对或绝对路径，以/结束',
			'file-name-rule'     => '文件命名规则：{Y}{m}{d}{H}{i}{s}{number}{unixtime}，可以不设置',
		);
		*/
		
		$this->config = $_config;
	}
	
	/**
	 * @throws SunException
	 */
	public function upload()
	{
		if( isset($_SERVER['HTTP_CONTENT_DISPOSITION']) )
		{
			$this->html5Upload();
		}
		else
		{
			$this->normalUpload();
		}
		
		return $this->result;
	}
	
	//针对html5方式的上传(还没处理批量上传的问题)
	private function html5Upload()
	{
		$v = array();
		preg_match('/attachment;\s+name="(.+?)";\s+filename="(.+?)"/i', $_SERVER['HTTP_CONTENT_DISPOSITION'], $v);
		/*
		$v = Array
		(
		    [0] => attachment; name="filedata"; filename="96601411.gif"
		    [1] => filedata
		    [2] => 96601411.gif
		)*/
		if(!$v[2]) throw new Exception('文件上传错误，请检查:10001');
		
		$this->result['file-name'] = $this->createFileName();
		$fileParse = $this->parseFile($v[2]);
		$this->result['file-type'] = $fileParse['type'];
		$this->result['file-full-name'] = $this->result['file-name'] . '.' . $this->result['file-type'];
		$this->result['file-path'] = $this->config['file-path'];
		$this->result['file-full-path'] = $this->config['file-path'] . date('Y/m/d/');
		$this->result['file-short-path'] = date('Y/m/d/');
		
		//文件格式检查
		$allowFileType = explode('|', $this->config['file-type']);
		if($this->config['file-type'] && !in_array($fileParse['type'], $allowFileType)) throw new Exception('只允许上传[' . $this->config['file-type'] . ']格式的文件的文件:10002');
		//大小检查
		//$fileSize = filesize(file_get_contents("php://input"));
		//if($fileSize / 1024 > $this->config['file-max-size']) throw new Exception('文件上传超过限制大小,只允许上传小于或等于' . $this->config['file-max-size'] . 'kb的文件:10003');
		//创建路径
		if( !file_exists(realpath($this->result['file-path']) . date('/Y')) ) mkdir( realpath($this->result['file-path']) . date('/Y') );
		if( !file_exists(realpath($this->result['file-path']) . date('/Y/m')) ) mkdir( realpath($this->result['file-path']) . date('/Y/m') );
		if( !file_exists(realpath($this->result['file-path']) . date('/Y/m/d')) ) mkdir( realpath($this->result['file-path']) . date('/Y/m/d') );
		file_put_contents($this->result['file-full-path'] . $this->result['file-full-name'], file_get_contents("php://input"));
	}
	
	//非html5方式上传
	private function normalUpload()
	{
		$this->check();
		$this->move();
	}
	
	/**
	 * @throws SunException
	 */
	private function check()
	{
		foreach($_FILES as $k => $v)
		{
			switch($v['error'])
			{
				case UPLOAD_ERR_INI_SIZE :
					throw new Exception('上传的文件超过了限制的大小:00001');
					break;
				case UPLOAD_ERR_FORM_SIZE :
					throw new Exception('上传的文件超过了限制的大小:00002');
					break;
				case UPLOAD_ERR_PARTIAL :
					throw new Exception('文件上传出错，请重试:00003');
					break;
				case UPLOAD_ERR_NO_FILE :
					throw new Exception('请选择要上传的文件:00004');
					break;
				case UPLOAD_ERR_NO_TMP_DIR :
					throw new Exception('文件上传发生异常，请联系管理员:00005');
					break;
				case UPLOAD_ERR_CANT_WRITE :
					throw new Exception('文件上传发生异常，请联系管理员:00006');
					break;
			}
			
			if( !is_uploaded_file($v['tmp_name']) ) throw new Exception('非法的数据上传:00020');
			$fileParse = $this->parseFile($v['name']);
			$allowFileType = explode('|', $this->config['file-type']);
			if($this->config['file-type'] && !in_array($fileParse['type'], $allowFileType)) throw new Exception('只允许上传' . $this->config['file-type'] . '格式的文件的文件');
			if($v['size'] / 1024 > $this->config['file-max-size']) throw new Exception('文件上传超过限制大小,只允许上传小于或等于' . $this->config['file-max-size'] . 'kb的文件');
			//if($v['size'] / 1024 > $this->config['file-max-size']) throw new Exception('文件上传超过限制大小,只允许上传小于或等于' . $this->config['file-max-size'] . 'kb的文件');
		}
	}
	
	private function move()
	{
		foreach($_FILES as $k => $v)
		{
			$this->result['file-name'] = $this->createFileName();
			$fileParse = $this->parseFile($v['name']);
			$this->result['file-type'] = $fileParse['type'];
			$this->result['file-full-name'] = $this->result['file-name'] . '.' . $this->result['file-type'];
			$this->result['file-path'] = $this->config['file-path'];
			$this->result['file-full-path'] = $this->config['file-path'] . date('Y/m/d/');
			$this->result['file-short-path'] = date('Y/m/d/');
			if( !file_exists(realpath($this->result['file-path']) . date('/Y')) ) mkdir( realpath($this->result['file-path']) . date('/Y') );
			if( !file_exists(realpath($this->result['file-path']) . date('/Y/m')) ) mkdir( realpath($this->result['file-path']) . date('/Y/m') );
			if( !file_exists(realpath($this->result['file-path']) . date('/Y/m/d')) ) mkdir( realpath($this->result['file-path']) . date('/Y/m/d') );
			$moveRes = move_uploaded_file($v['tmp_name'], $this->result['file-full-path'] . $this->result['file-full-name']);
			if(!$moveRes) throw new Exception('文件上传发生异常，请联系管理员:00021');
		}
	}
	
	private function parseFile($file)
	{
		$file = basename($file);
		$arr = explode('.', $file);
		$fileType = $arr[count($arr) - 1] ;
		array_pop($arr);
		$fileName = implode('.', $arr);
		
		return array(
			'name' => $fileName,
			'type' => strtolower($fileType)
		);
	}
	
	private function createFileName()
	{
		$t = explode(" ", microtime());
		return $t[1] . $t[0] * 100000000;
	}
}
?>